﻿// -----------------------------------------------------------------------
// <copyright file="DateTimeSerializer.cs" company="none">
// Copyright (c) 2012 M. Alberti, xanatos(at)live.it
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// </copyright>
// -----------------------------------------------------------------------

namespace FluentSerializer.Serializers
{
    using System;
    using System.Linq.Expressions;
    using System.Reflection;

    /// <summary>
    /// 
    /// </summary>
    public static class DateTimeSerializer
    {
        /// <summary>
        /// 
        /// </summary>
        private static readonly MethodInfo DateTimeFromBinary = typeof(DateTime).GetMethod("FromBinary", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(long) }, null);

        /// <summary>
        /// 
        /// </summary>
        private static readonly MethodInfo DateTimeToBinary = typeof(DateTime).GetMethod("ToBinary", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static Descriptor BuildDateTimeSerializer()
        {
            Type type = typeof(DateTime);

            Descriptor descriptor1 = Serializer.GetSerializer(typeof(long));

            ParameterExpression item = Expression.Parameter(type);
            ParameterExpression parameters = null;

            LambdaExpression deserializeExpression;
            LambdaExpression serializeExpression;
            LambdaExpression sizeExpression;

            /***/
            {
                Expression deserializedItem = Serializer.MakeFromLambda(descriptor1.DeserializeExpression, descriptor1.IsUniversal, Serializer.ReaderExpression, descriptor1.DefaultExpression, parameters);

                deserializeExpression = Serializer.MakeLambda(Expression.Call(DateTimeFromBinary, deserializedItem), descriptor1.IsUniversal, Serializer.ReaderExpression, item, parameters);
            }

            /***/
            {
                Expression serializedItem = Expression.Call(item, DateTimeToBinary);

                serializeExpression = Serializer.MakeLambda(Serializer.MakeFromLambda(descriptor1.SerializeExpression, descriptor1.IsUniversal, Serializer.WriterExpression, serializedItem, parameters), descriptor1.IsUniversal, Serializer.WriterExpression, item, parameters);
            }

            /***/
            {
                sizeExpression = Serializer.MakeLambda(Serializer.MakeFromLambda(descriptor1.SizeExpression, descriptor1.IsUniversal, descriptor1.DefaultExpression, parameters), descriptor1.IsUniversal, item, parameters);
            }

            var descriptor2 = new Descriptor(type, descriptor1.IsUniversal, deserializeExpression, DeserializationHandling.RequireAssignment, serializeExpression, sizeExpression);
            return descriptor2;
        }
    }
}